package com.sm.filemanagelibrary.util;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import androidx.annotation.DrawableRes;

import com.scorpio.baselibrary.utils.FileSizeUtil;
import com.scorpio.baselibrary.utils.Platform;
import com.sm.filemanagelibrary.R;
import com.sm.filemanagelibrary.model.FileEntity;
import com.sm.filemanagelibrary.model.FolderEntity;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * created by zhud on 2019/9/27
 */
public class FileLoadingUtil {
    private static final ExecutorService executorService = Executors.newSingleThreadExecutor();
    private static Platform mPlatform;
    public static final String AUDIO_NAME_KEY = "__audio__";
    public static final String FILE_DOC_KEY = "__doc__";
    public static final String FILE_XLS_KEY = "__xls__";
    public static final String FILE_APK_KEY = "__apk__";
    public static final String FILE_FILE_KEY = "__file__";
    private static final String[] SELECTED_IMAGE_KEY = new String[]{
            MediaStore.Images.Media.BUCKET_DISPLAY_NAME
            , MediaStore.Images.Media.DATA
            , MediaStore.Images.Media.SIZE
            , MediaStore.Images.Media.MIME_TYPE
            , MediaStore.Images.Media.DATE_MODIFIED
    };

    private static final String[] SELECTED_AUDIO_KEY = new String[]{
            AUDIO_NAME_KEY
            , MediaStore.Audio.Media.DATA
            , MediaStore.Audio.Media.SIZE
            , MediaStore.Audio.Media.MIME_TYPE
            , MediaStore.Audio.Media.DATE_MODIFIED
    };

    private static final String[] SELECTED_VIDEO_KEY = new String[]{
            MediaStore.Video.Media.BUCKET_DISPLAY_NAME
            , MediaStore.Video.Media.DATA
            , MediaStore.Video.Media.SIZE
            , MediaStore.Video.Media.MIME_TYPE
            , MediaStore.Video.Media.DATE_MODIFIED
    };

    private static final String[] SELECTED_FILE_KEY = new String[]{
            FILE_FILE_KEY
            , MediaStore.Files.FileColumns.DATA
            , MediaStore.Files.FileColumns.SIZE
            , MediaStore.Files.FileColumns.MIME_TYPE
            , MediaStore.Files.FileColumns.DATE_MODIFIED
    };

    static {
        mPlatform = Platform.get();
    }

    /**
     * 根据类型获取图片资源
     *
     * @param type
     * @return
     */
    @DrawableRes
    public static int getFileImageRes(FileTypeUtil.Type type) {
        switch (type) {
            case Form:
                return R.drawable.icon_file_form;
            case Html:
                return R.drawable.icon_file_txt;
            case Text:
                return R.drawable.icon_file_txt;
            case Audio:
                return R.drawable.icon_file_audio;
            case Image:
                return R.drawable.icon_file_image;
            case Video:
                return R.drawable.icon_file_video;
            case Package:
                return R.drawable.icon_file_package;
            case APP:
                return R.drawable.icon_file_app;
            case Document:
                return R.drawable.icon_file_document;
            case Unknown:
            default:
                return R.drawable.icon_file_default;
        }
    }

    /**
     * 加载路劲文件
     *
     * @param path
     * @param loadingListener
     */
    public static void loadingPathFile(final String path, final OnFileLoadingListener loadingListener) {
        new Thread() {
            @Override
            public void run() {
                final List<FolderEntity> folders = new ArrayList<>();
                List<FileEntity> files = new ArrayList<>();
                try {
                    File rootPath = new File(path);
                    File[] fs = rootPath.listFiles();
                    for (File file : fs) {
                        FileEntity entity = new FileEntity();
                        entity.name = file.getName();
                        entity.path = file.getAbsolutePath();
                        entity.lastModified = file.lastModified();
                        files.add(entity);
                        if (file.isDirectory()) {
                            entity.isDirectory = true;
                            entity.size = file.listFiles().length;
                        } else {
                            String[] tna = file.getName().split("\\.");
                            if (tna.length > 1) entity.type = tna[tna.length - 1];
                            entity.size = FileSizeUtil.getFileSize(file);
                        }
                    }
                    Collections.sort(files);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                final FolderEntity folderEntity = new FolderEntity();
                folderEntity.name = "All";
                folderEntity.setSubItems(files);
                folders.add(folderEntity);
                mPlatform.execute(new Runnable() {
                    @Override
                    public void run() {
                        loadingListener.onfileLoading(folders);
                    }
                });
            }
        }.start();
    }

    /**
     * 加载手机音视频文件
     *
     * @param mContext
     * @param loadingListener
     */
    public static void loadingPhoneVideo(final Context mContext, final OnFileLoadingListener loadingListener) {
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                final List<FolderEntity> folders = new ArrayList<>();
                try {
                    Uri mAudioUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                    Uri mVideoUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                    ContentResolver mContentResolver = mContext.getContentResolver();
                    Cursor mCursor = mContentResolver.query(mAudioUri,
                            null
                            , null
                            , null
                            , MediaStore.Audio.Media.DATE_MODIFIED);
                    folders.addAll(toCursorTransitionFolderEntitys(mCursor, SELECTED_AUDIO_KEY));
                    mCursor = mContentResolver.query(mVideoUri,
                            null
                            , null
                            , null
                            , MediaStore.Video.Media.DATE_MODIFIED);
                    folders.addAll(toCursorTransitionFolderEntitys(mCursor, SELECTED_VIDEO_KEY));
                    Collections.sort(folders);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                mPlatform.execute(new Runnable() {
                    @Override
                    public void run() {
                        loadingListener.onfileLoading(folders);
                    }
                });
            }
        });
    }

    /**
     * 加载手机文档
     *
     * @param mContext
     * @param loadingListener
     */
    public static void loadingPhoneDocument(final Context mContext, final OnFileLoadingListener loadingListener) {
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                final List<FolderEntity> foldersList = new ArrayList<>();
                try {
                    Map<String, FolderEntity> folders = new HashMap();
                    ContentResolver mContentResolver = mContext.getContentResolver();
                    String select = "(" + MediaStore.Files.FileColumns.DATA + " LIKE '%.doc'" + " or " + MediaStore.Files.FileColumns.DATA + " LIKE '%.docx'" + ")";
                    Cursor cursor = mContentResolver.query(MediaStore.Files.getContentUri("external"),
                            null
                            , select
                            , null
                            , MediaStore.Files.FileColumns.DATE_MODIFIED);

                    if (cursor != null) {
                        while (cursor.moveToNext()) {
                            FileEntity entity = toCursorTransitionFileEntity(cursor, SELECTED_FILE_KEY);
                            FolderEntity folderEntity = folders.get(FILE_DOC_KEY);
                            if (folderEntity == null) {
                                folderEntity = new FolderEntity();
                                folderEntity.name = "word";
                            }
                            entity.type = "doc";
                            folderEntity.addSubItem(entity);
                            folders.put(FILE_DOC_KEY, folderEntity);
                        }
                        cursor.close();
                    }
                    select = "(" + MediaStore.Files.FileColumns.DATA + " LIKE '%.xls'" + " or " + MediaStore.Files.FileColumns.DATA + " LIKE '%.xlsx'" + ")";
                    cursor = mContentResolver.query(MediaStore.Files.getContentUri("external"),
                            null
                            , select
                            , null
                            , MediaStore.Files.FileColumns.DATE_MODIFIED);
                    if (cursor != null) {
                        while (cursor.moveToNext()) {
                            FileEntity entity = toCursorTransitionFileEntity(cursor, SELECTED_FILE_KEY);
                            FolderEntity folderEntity = folders.get(FILE_XLS_KEY);
                            if (folderEntity == null) {
                                folderEntity = new FolderEntity();
                                folderEntity.name = "excel";
                            }
                            entity.type = "xls";
                            folderEntity.addSubItem(entity);
                            folders.put(FILE_XLS_KEY, folderEntity);
                        }
                        cursor.close();
                    }
                    foldersList.addAll(new ArrayList<>(folders.values()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
                mPlatform.execute(new Runnable() {
                    @Override
                    public void run() {
                        loadingListener.onfileLoading(foldersList);
                    }
                });
            }
        });
    }

    /**
     * 加载手机apk
     *
     * @param mContext
     * @param loadingListener
     */
    public static void loadingPhoneApp(final Context mContext, final OnFileLoadingListener loadingListener) {
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                final List<FolderEntity> foldersList = new ArrayList<>();
                try {
                    ContentResolver mContentResolver = mContext.getContentResolver();
                    String select = "(" + MediaStore.Files.FileColumns.DATA + " LIKE '%.apk' )";
                    Cursor cursor = mContentResolver.query(MediaStore.Files.getContentUri("external"),
                            null
                            , select
                            , null
                            , MediaStore.Files.FileColumns.DATE_MODIFIED);
                    List<FileEntity> entities = new ArrayList<>();
                    if (cursor != null) {
                        while (cursor.moveToNext()) {
                            FileEntity entity = toCursorTransitionFileEntity(cursor, SELECTED_FILE_KEY);
                            entity.type = "apk";
                            entities.add(entity);
                        }
                        cursor.close();
                    }
                    FolderEntity installiertEntity = new FolderEntity(mContext.getString(R.string.file_string_00008));
                    FolderEntity onInstalliertEntity = new FolderEntity(mContext.getString(R.string.file_string_00009));
                    for (FileEntity entity : entities) {
                        if (FileTypeUtil.isAvilible(mContext, entity.path)) {
                            installiertEntity.addSubItem(entity);
                        } else {
                            onInstalliertEntity.addSubItem(entity);
                        }
                        entity.name = FileTypeUtil.getPackageName(mContext, entity.path);
                    }
                    foldersList.add(installiertEntity);
                    foldersList.add(onInstalliertEntity);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                mPlatform.execute(new Runnable() {
                    @Override
                    public void run() {
                        loadingListener.onfileLoading(foldersList);
                    }
                });
            }
        });
    }

    /**
     * 加载手机图片
     *
     * @param mContext
     * @param loadingListener
     */
    public static void loadingPhoneImage(final Context mContext, final OnFileLoadingListener loadingListener) {
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                final List<FolderEntity> folders = new ArrayList<>();
                try {
                    Uri mImageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                    ContentResolver mContentResolver = mContext.getContentResolver();
                    //只查询jpeg和png的图片
                    Cursor mCursor = mContentResolver.query(mImageUri,
                            null
                            , null
                            , null
                            , MediaStore.Images.Media.DATE_MODIFIED);
                    folders.addAll(toCursorTransitionFolderEntitys(mCursor, SELECTED_IMAGE_KEY));
                } catch (Exception e) {
                    e.printStackTrace();
                }
                mPlatform.execute(new Runnable() {
                    @Override
                    public void run() {
                        loadingListener.onfileLoading(folders);
                    }
                });
            }
        });
    }

    /**
     * 读取Cursor转化成list 加载完毕自动close
     *
     * @param cursor
     * @param selectKey
     * @return
     */
    private static List<FolderEntity> toCursorTransitionFolderEntitys(Cursor cursor, String[] selectKey) {
        Map<String, FolderEntity> folders = new HashMap();
        if (cursor != null) {
            while (cursor.moveToNext()) {
                FileEntity entity = toCursorTransitionFileEntity(cursor, selectKey);
                FolderEntity folderEntity = folders.get(entity.parent);
                if (folderEntity == null) {
                    folderEntity = new FolderEntity();
                    folderEntity.name = entity.parent;
                }
                folderEntity.addSubItem(entity);
                folders.put(entity.parent, folderEntity);
            }
        }
        cursor.close();
        List<FolderEntity> folderList = new ArrayList<>(folders.values());
        Collections.sort(folderList);
        for (FolderEntity folderEntity : folderList) {
            Collections.sort(folderEntity.getSubItems());
        }
        return folderList;
    }

    /**
     * 读取Cursor单个转化成FileEntity对象
     *
     * @param cursor
     * @param selectKey
     * @return
     */
    private static FileEntity toCursorTransitionFileEntity(Cursor cursor, String[] selectKey) {
        //获取图片的路径
        FileEntity entity = new FileEntity();
        entity.isDirectory = false;
        if (selectKey[0].equals(AUDIO_NAME_KEY) || selectKey[0].equals(FILE_FILE_KEY)) {
            entity.parent = AUDIO_NAME_KEY;
        } else {
            entity.parent = cursor.getString(cursor.getColumnIndex(selectKey[0]));
        }
        entity.path = cursor.getString(cursor.getColumnIndex(selectKey[1]));
        entity.name = Uri.parse(entity.path).getLastPathSegment();
        entity.size = cursor.getLong(cursor.getColumnIndex(selectKey[2]));
        entity.type = cursor.getString(cursor.getColumnIndex(selectKey[3]));
        entity.lastModified = cursor.getLong(cursor.getColumnIndex(selectKey[4])) * 1000;
        return entity;
    }
}
